package gr.gsis.efmy.model;

import gr.gsis.efmy.model.annotation.Alphanumeric;
import gr.gsis.efmy.model.annotation.Amount;
import gr.gsis.efmy.model.annotation.Numeric;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.lang.reflect.Field;
import java.util.logging.Logger;

public class DataSerializer {
	private static DataSerializer instance = null;
	
	private static Logger LOGGER = Logger.getLogger("DataSerializer");
	
	protected DataSerializer() {}
	
	public static DataSerializer getInstance() {
		if (null == instance) {
			instance = new DataSerializer();
		}
		return instance;
	}
	
	public void createFile(String filename, PayrollTaxAggregate data) throws IOException {
		StringBuffer sbHeader = new StringBuffer();
		for(Field field: data.getHeader().getClass().getDeclaredFields()) {
			LOGGER.info(field.getName());
			try {
				sbHeader.append(serializeField(field, data.getHeader()));
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		LOGGER.info("Header: [" + sbHeader.toString() + "]");
		
		File file = new File(filename);
		if (!file.exists()) {
			try {
				file.createNewFile();
				LOGGER.info("File has been created!");
			} catch (IOException e) {
				LOGGER.severe("Failed to create file." + e.getMessage());
			}
			
		}
		
		Writer writer = new BufferedWriter(new FileWriter(file));
		try {
			writer.write(sbHeader.toString());
		} finally {
			writer.close();
		}
	}
	
	private String serializeField(Field field, Object obj) throws Exception {
		if (null == field.getAnnotations() || field.getAnnotations().length == 0) {
			LOGGER.info("No annotations found");
			try {
				LOGGER.info("Type: " + field.getType());
				LOGGER.info("Returning value : " + field.get(obj));
				Object value = field.get(obj);
				if (value instanceof String ) {
					return (String) value;
				} else if (value instanceof Short) {
					return Short.toString((Short) value);
				} else {
					return "";
				}
			} catch (IllegalArgumentException e) {
				e.printStackTrace();
				return null;
			} catch (IllegalAccessException e) {
				e.printStackTrace();
				return null;
			}
		}
		
		if (field.isAnnotationPresent(Alphanumeric.class)) {
			
		} else if(field.isAnnotationPresent(Numeric.class)) {
			Numeric numeric = field.getAnnotation(Numeric.class);
			Object value = field.get(obj);
			if (value instanceof String) {
				return (String) value;
			} else if (value instanceof Short) {
				return Short.toString((Short) value); 
			}
			
		} else if (field.isAnnotationPresent(Amount.class)) {
			
		}

		return null;
	}
	
	private String padRight(String s, int n) {
	     return String.format("%1$-" + (n - s.length()) + "s", s);  
	}
}
